/*================================================================================
*
*
*                                   
*
*
* 项目名称: mcp2515-spi-can-demo
* 文件名称: mcp2515_can_app.c
* 创建日期: 21-02-03
* 文件描述: 
*
================================================================================*/
#include "main.h"
#include "gpio.h"
#include "mcp2515.h"
#include "RGB_LED.h"
#include "spi.h"

#include "mcp2515_can_comm.h"

//-private code------------------------------------------------------------------
static void MCP2515CAN_TxMsg(void);

//-private data------------------------------------------------------------------
static McpCanFrm_t s_MsgRx;
static uint8_t flgRxOk, flgTxTickOk=1;

//-public data-------------------------------------------------------------------

/********************************************************************************
*函数功能: 
    初始化MCP2515 CAN功能 125kbps
*修改记录: 
*日期:                作者:                摘要:
      21-02-03             YummoShin            Create
********************************************************************************/
void InitMCP2515CAN(void)
{
    McpBitTime_t BitTime=
    {
        .u8BRP = 1,
        .u8PRSEG = 1,
        .u8PHSEG1 = 6,
        .u8PHSEG2 = 5,
        .u8SJW = 0
    };
    McpRxFlt_t Filter={.u16SID=0x01, .u8EXIDE=1, .u32EID=0x01};
    McpRxMsk_t Mask={.u16SID=0x01, .u32EID=0x01};

    __HAL_SPI_ENABLE(&hspi2);

    MCP2515CfgBitTime(&BitTime); //配置CAN速率
    MCP2515SetRxFlt(MCP_RXF0, &Filter); //配置验收器
    MCP2515SetRxMsk(MCP_RXM0, &Mask);
    MCP2515EnableOSM(); //配置单触发发送模式
    MCP2515SetMode(MCP_REQOP_NORMAL); //配置正常工作模式
}

/********************************************************************************
*函数功能: 
    CAN通讯处理主函数
*修改记录: 
*日期:                作者:                摘要:
      21-02-03             YummoShin            Create
********************************************************************************/
void ProcessMCP2515CAN_Comm(void)
{
    static uint32_t u32Tick;
    RgbLed_t led;

    //定时发送报文
    if(flgTxTickOk)
    {
        flgTxTickOk = 0;
        MCP2515CAN_TxMsg();
        u32Tick = HAL_GetTick();
    }
    if( (HAL_GetTick()-u32Tick) >=500 )
    {
        flgTxTickOk = 1;
    }

    if(flgRxOk)
    {
        flgRxOk = 0;
        led.u8R = s_MsgRx.u8Data[0];
        led.u8G = s_MsgRx.u8Data[1];
        led.u8B = s_MsgRx.u8Data[2];
        led.u8L = s_MsgRx.u8Data[4];

        RgbLedCtrl(&led);
    }
}

/********************************************************************************
*函数功能: 
    单触发模式发送,保证实时性
*修改记录: 
*日期:                作者:                摘要:
      21-02-03             YummoShin            Create
********************************************************************************/
static void MCP2515CAN_TxMsg(void)
{
    McpCanFrm_t CanMsg=
    {
        .u16SID=1,
        .u8DLC=5,
        .u8Data[0]=g_LedState.u8R,
        .u8Data[1]=g_LedState.u8G,
        .u8Data[2]=g_LedState.u8B,
        .u8Data[3]=g_LedState.u8L,
        .u8Data[4]=g_LedState.flgAdj
    };

    MCP2515DisableIT(MCP_IT_RX0); //禁止MCP2515中断
    
    MCP2515WrMsg2Buf(MCP_TXB0, &CanMsg); //装载报文
    MCP2515RTS(MCP_TXB0); //请求发送

    MCP2515EnableIT(MCP_IT_RX0); //打开MCP2515中断
}

/********************************************************************************
*函数功能: 
    MCP2515中断请求,使用外部中断,配置为接收中断,只处理接收中断
*修改记录: 
*日期:                作者:                摘要:
      21-02-03             YummoShin            Create
********************************************************************************/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    (void)GPIO_Pin;
    MCP2515GetMsg(MCP_RXB0, &s_MsgRx); //获取接收的数据,设置标志位
    flgRxOk = 1;
    MCP2515ClrITFLG(MCP_IT_RX0); //清除中断标志位
}
